import { HolderOutlined } from '@ant-design/icons'
import { DndContext } from '@dnd-kit/core'
import { restrictToVerticalAxis } from '@dnd-kit/modifiers'
import { arrayMove, SortableContext, useSortable, verticalListSortingStrategy } from '@dnd-kit/sortable'
import { CSS } from '@dnd-kit/utilities'
import { Button, Table } from 'antd'
import { createContext, useContext, useMemo } from 'react'

const RowContext = createContext({})
const DragHandle = () => {
  const { setActivatorNodeRef, listeners } = useContext(RowContext)
  return (
    <Button
      type='text'
      size='small'
      icon={<HolderOutlined />}
      style={{
        cursor: 'move',
      }}
      ref={setActivatorNodeRef}
      {...listeners}
    />
  )
}
const sort = {
  title: '拖动排序',
  dataIndex: 'sort',
  width: 120,
  className: 'drag-visible',
  render: () => <DragHandle />,
}
const Row = props => {
  const { attributes, listeners, setNodeRef, setActivatorNodeRef, transform, transition, isDragging } = useSortable({
    id: props['data-row-key'],
  })
  const style = {
    ...props.style,
    transform: CSS.Translate.toString(transform),
    transition,
    ...(isDragging
      ? {
          position: 'relative',
          zIndex: 9999,
        }
      : {}),
  }
  const contextValue = useMemo(
    () => ({
      setActivatorNodeRef,
      listeners,
    }),
    [setActivatorNodeRef, listeners],
  )
  return (
    <RowContext.Provider value={contextValue}>
      <tr {...props} ref={setNodeRef} style={style} {...attributes} />
    </RowContext.Provider>
  )
}
const SortableTable = props => {
  const { dataSource, columns, onChange, scroll } = props
  const onDragEnd = ({ active, over }) => {
    if (active.id !== over?.id) {
      onChange(prevState => {
        const activeIndex = prevState.findIndex(record => record.key === active?.id)
        const overIndex = prevState.findIndex(record => record.key === over?.id)
        return arrayMove(prevState, activeIndex, overIndex)
      })
    }
  }
  return (
    <DndContext modifiers={[restrictToVerticalAxis]} onDragEnd={onDragEnd}>
      <SortableContext items={dataSource.map(i => i.key)} strategy={verticalListSortingStrategy}>
        <Table
          rowKey='key'
          columns={[sort, ...columns]}
          dataSource={dataSource}
          pagination={false}
          scroll={scroll}
          components={{
            body: {
              row: Row,
            },
          }}
        />
      </SortableContext>
    </DndContext>
  )
}
export default SortableTable
